#ifndef MINIOBJECT_H
#define MINIOBJECT_H

#include <string>
#include <fstream>
#include <vector>

// 引入 Eigen 库
#include <eigen3/Dense>
#include <eigen3/Sparse>

#include "Vector3f.h"
#include "Matrix.h"
#include "Quaternion.h"
#include "Calculus.h"
#include "Polynomial.h"
#include "ODESolver.h"

namespace XYF
{
    /**
     * @file: MiniObject.h
     * @author: xingyifan
     * @date: 2023-03-17 21:13
     *
     * @description: 简化数组类型
     */

    template <class T>
    using MiniArray = std::vector<T>;

    template <class T>
    using MiniArray2D = MiniArray<MiniArray<T>>;

    template <class T>
    using MiniArray3D = MiniArray<MiniArray2D<T>>;

    template <class T>
    using MiniArray4D = MiniArray<MiniArray3D<T>>;

    /**
     * @file: MiniObject.h
     * @author: xingyifan
     * @date: 2023-04-22 23:14
     *
     * @description: 定义参量形式
     */

    using Func13 = std::function<Vector3f(Real)>;       // 一元函数 R -> R3
    using Func23 = std::function<Vector3f(Real, Real)>; // 二元函数 R2 -> R3

    /**
     * @file: MiniObject.h
     * @author: xingyifan
     * @date: 2023-03-10 21:25
     *
     * @description: 作为所有物体的基类
     */

    class MiniObject
    {
    public:
        enum
        {
            cloud,
            B_spline_curve,
            B_spline_surface,
            mesh,
            discrete_curve,
            para_curve,
            discrete_surface,
            para_surface
        };

        virtual ~MiniObject();     // 虚析构函数
        virtual int GetType() = 0; // 返回物体类型
    };

    /**
     * @file: MiniObject.h
     * @author: xingyifan
     * @date: 2023-05-02 23:13
     *
     * @description: B 样条基函数的基本算法
     */

    int FindSpan(Real u, int p, const MiniArray<Real> &knots);                                    // 找到 u 所在的节点区间 [u_i, u_{i+1})
    int FindSpanMult(int k, Real u, int p, const MiniArray<Real> &knots);                         // 找到 [u_k,u_{k+1}) 和之前 u 出现的次数
    MiniArray<Real> BasisFuncs(int i, Real u, int p, const MiniArray<Real> &knots);               // 计算所有代入 u 后不为零的 p 次基函数
    MiniArray2D<Real> DerivBasisFuncs(int d, int i, Real u, int p, const MiniArray<Real> &knots); // 计算所有代入 u 后不为零的 d 阶导基函数
    MiniArray2D<Real> AllBasisFuncs(int i, Real u, int p, const MiniArray<Real> &knots);          // 计算所有代入 u 后不为零的不大于 p 次基函数

    /**
     * @file: MiniObject.h
     * @author: xingyifan
     * @date: 2023-05-02 23:14
     *
     * @description: 离散点常用算法
     */

    MiniArray<Real> Normalized(const MiniArray<Real> &t);                       // 参数规范化到 [0,1] 上
    MiniArray<Vector3f> OrientBoundingBox(const MiniArray<Vector3f> &points);   // 获得点云的有向包围盒
}

#endif // MINIOBJECT_H
